#include "StdAfx.h"

#include "OpenCV/cv.h"
#include "OpenCV/cxcore.h"
#include "OpenCV/cxtypes.h"
#include "OpenCV/highgui.h"

#include "Color.h"
#include "Image.h"

#include "DataImage.h"

DataImage::DataImage()
{}

DataImage::DataImage(unsigned x, unsigned y) : _data(cvCreateImage(cvSize(x, y), IPL_DEPTH_8U , 3)) {}
DataImage::DataImage(const std::string& fileName) : _data(cvLoadImage(fileName.c_str())) {}
Color DataImage::GetColor(double x, double y)
	{
	if (x > Width())
		x--;
	if (y > Height())
		y--;

	x -= x / Width();
	y -= y / Height();
	unsigned char R, G, B;

	unsigned count = (unsigned)(floor(x) * 3 + floor(y) * _data->widthStep);
	double yRation = y - floor(y), xRatio = x - floor(x);

	R = (unsigned char)(((unsigned char)_data->imageData[count + 2] * (1 - xRatio) + (unsigned char)_data->imageData[count + 5]  * xRatio) * (1 - yRation) + 
		((unsigned char)_data->imageData[count + 2 + _data->widthStep] * (1 - xRatio) + (unsigned char)_data->imageData[count + 5 + _data->widthStep]  * xRatio) * yRation);
	G = (unsigned char)(((unsigned char)_data->imageData[count + 1] * (1 - xRatio) + (unsigned char)_data->imageData[count + 4]  * xRatio) * (1 - yRation) + 
		((unsigned char)_data->imageData[count + 1 + _data->widthStep] * (1 - xRatio) + (unsigned char)_data->imageData[count + 4 + _data->widthStep] * xRatio) * yRation);
	B = (unsigned char)(((unsigned char)_data->imageData[count] * (1 - xRatio) + (unsigned char)_data->imageData[count + 3] * xRatio) * (1 - yRation) + 
		((unsigned char)_data->imageData[count + _data->widthStep] * (1 - xRatio) + (unsigned char)_data->imageData[count + 3 + _data->widthStep] * xRatio) * yRation);
	return Color(R / 255.0, G / 255.0, B / 255.0);
}

void DataImage::SetColor(unsigned pixelCount, const Color& color)
{
	_data->imageData[pixelCount] = (char)std::max(std::min((int)floor(color.Z * 255.0), 255), 0);
	_data->imageData[pixelCount + 1] = (char)std::max(std::min((int)floor(color.Y * 255.0), 255), 0);
	_data->imageData[pixelCount + 2] = (char)std::max(std::min((int)floor(color.X * 255.0), 255), 0);
}

unsigned DataImage::Width()
{
	return _data->width;
}

unsigned DataImage::Height()
{
	return _data->height;
}

unsigned DataImage::WidthStep()
{
	return _data->widthStep;
}

DataImage::~DataImage()
{
	if (_data != NULL)
		cvReleaseImage(&_data);
}

void DataImage::DrawOnScreen()
{
	cvNamedWindow("RayTracer", 1);
	cvShowImage("RayTracer", _data);
	cvWaitKey();
	cvDestroyWindow("RayTracer");
}
